export default class DeepQuery {
	constructor(config) {
		this.flatObj = {}
		const {
			params,
			data,
			method
		} = config
		this.method = method
		let paramsObj = {}
		let bodyObj = {}
		// boby ARR  优先级最高
		if (Array.isArray(data)) {
			return this.value = this.deeps(data)
		}
		// query ARR  次之
		if (Array.isArray(params)) {
			let parArr = JSON.parse(JSON.stringify(params))
			let queryArr = []
			queryArr = this.initQuery(parArr)
			return this.value = this.deeps(queryArr)
		}
		// 入参在请求头并且是get 数字全部转为字符串
		if (this.objectLength(params || {})) {
			let parObj = JSON.parse(JSON.stringify(params))
			paramsObj = this.initQuery(parObj)
		}
		// body对象
		if (this.objectLength(data || {})) {
			bodyObj = data
		}
		// 合并query 和 body 对象
		this.value = this.deeps({
			...paramsObj,
			...bodyObj
		})

	}

	// 开始deep
	deeps(params) {
		if (Array.isArray(params)) {
			this.deppArr(params, '')
		} else {
			for (const key in params) {
				if (Object.hasOwnProperty.call(params, key)) {
					if (this.isObject(params[key])) {
						this.deepObj(params[key], key)
					} else if (Array.isArray(params[key])) {
						this.deppArr(params[key], key)
					} else {
						this.flatObj[key] = params[key]
					}
				}
			}
		}
		return this.sortData()
	}

	// deep对象
	deepObj(obj, name) {
		for (const key in obj) {
			if (Object.hasOwnProperty.call(obj, key)) {
				if (this.isObject(obj[key])) {
					this.deepObj(obj[key], name + '.' + key)
				} else if (Array.isArray(obj[key])) {
					this.deppArr(obj[key], name + '.' + key)
				} else {
					this.flatObj[name + '.' + key] = obj[key]
				}
			}
		}
	}

	// deep数组
	deppArr(arr, name) {
		arr.forEach((e, i) => {
			if (this.isObject(e)) {
				this.deepObj(e, name + '[' + i + ']')
			} else if (Array.isArray(e)) {
				this.deppArr(e, name + '[' + i + ']')
			} else {
				this.flatObj[name + '[' + i + ']'] = e
			}
		})
	}

	// 开始deep入参
	initQuery(params) {
		let queryObj = JSON.parse(JSON.stringify(params))
		if (Array.isArray(queryObj)) {
			this.deppQueryArr(queryObj)
		} else {
			this.deepQueryObj(queryObj)
		}
		return JSON.parse(JSON.stringify(queryObj))
	}

	// deep入参对象
	deepQueryObj(obj) {
		for (const key in obj) {
			if (Object.hasOwnProperty.call(obj, key)) {
				if (this.isObject(obj[key])) {
					this.deepQueryObj(obj[key])
				} else if (Array.isArray(obj[key])) {
					this.deppQueryArr(obj[key])
				} else if (obj[key] !== null && typeof(obj[key]) !== "undefined") {
					obj[key] = (obj[key] + "")
				}
			}
		}
	}

	// deep入参数组
	deppQueryArr(arr) {
		arr.forEach((e, i) => {
			if (this.isObject(e)) {
				this.deepQueryObj(e)
			} else if (Array.isArray(e)) {
				this.deppQueryArr(e)
			} else if (arr[i] !== null && typeof(arr[i]) !== "undefined") {
				arr[i] = (e + "")
			}
		})
	}

	// 是否是对象
	isObject(value) {
		return (
			typeof value === 'object' && value !== null && !Array.isArray(value)
		)
	}

	// 对象长度
	objectLength(obj) {
		return Object.keys(obj).length !== 0
	}

	// 排序
	sortData() {
		// 由于JSON.stringify 会打乱对象的排序 故此自己封装
		let sortStr = '{'
		let queryObj = {}
		for (const key in this.flatObj) {
			if (Object.hasOwnProperty.call(this.flatObj, key)) {
				if (this.method === 'post' || this.method === 'put') {
					// 兼容 stringify 处理方式 去除undefined
					if (typeof(this.flatObj[key]) !== 'undefined') {
						queryObj[key] = this.flatObj[key];
					}

				} else {
					queryObj[key] = this.flatObj[key];
				}

			}
		}
		const keys = Object.keys(queryObj)
		keys.sort().forEach((key, index) => {
			sortStr += `"${key}":${JSON.stringify(this.flatObj[key])}`
			if (index < keys.length - 1) {
				sortStr += ','
			}
		})
		sortStr += '}'
		return sortStr
	}
}